package org.apache.ibatis.type;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class BaseTypeHandler implements TypeHandler {

    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
            throws SQLException {
        if (parameter == null) {  // 参数为空

            if (jdbcType == null) { //

                try {
                    ps.setNull(i, JdbcType.OTHER.TYPE_CODE);  // PreparedStatement 设置null
                } catch (SQLException e) {
                    throw new TypeException("Error setting null parameter.  Most JDBC drivers require that the JdbcType must be specified for all nullable parameters. Cause: " + e, e);
                }
            } else {
                ps.setNull(i, jdbcType.TYPE_CODE);
            }

        } else { // 参数不为空

            // 为不为空的
            setNonNullParameter(ps, i, parameter, jdbcType);
        }
    }

    // 子类实现为 PreparedStatement 设置参数; 又是策略模式
    public abstract void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
            throws SQLException;


    public Object getResult(ResultSet rs, String columnName) throws SQLException {
        Object result = getNullableResult(rs, columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            return result;
        }
    }

    public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
        Object result = getNullableResult(cs, columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            return result;
        }
    }


    // 得到结果集
    public abstract Object getNullableResult(ResultSet rs, String columnName) throws SQLException;


    // 得到结果集
    public abstract Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

}

